package com.lagou.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


public class MultiChannelClient {

    public static Map<Integer, ChannelFuture> channels = new HashMap<>();

    /**
     * 初始化Bootstrap
     */
    public static final Bootstrap getBootstrap(EventLoopGroup group) {
        if (null == group) {
            group = new NioEventLoopGroup();
        }
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group).channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.handler(new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                // 添加自定义协议的编解码工具
                pipeline.addLast(new IdleStateHandler(0, 30, 0, TimeUnit.SECONDS));
                ch.pipeline().addLast(new StringEncoder());
                ch.pipeline().addLast(new StringDecoder());
                pipeline.addLast(new UserClientHandler());
            }
        });
        return bootstrap;
    }

    //   获取所有连接
    public static final void getChannel(List<String> addressLists) {

        for (int i = 0; i < addressLists.size(); i++) {
            Bootstrap bootstrap = getBootstrap(null);
            String serverAddress = (String) addressLists.get(i);
            String host = "";
            int port = 0;
            if (serverAddress!=null) {
                String[] array = serverAddress.split(":");
                if (array!=null && array.length==2) {

                    host = array[0];
                    port = Integer.parseInt(array[1]);
                }
            }
            bootstrap.remoteAddress(host, port);
            //异步连接tcp服务端
            int finalPort = port;
            String finalHost = host;
            String finalHost1 = host;
            int finalPort1 = port;
            ChannelFuture future = bootstrap.connect().addListener((ChannelFuture futureListener) -> {
                final EventLoop eventLoop = futureListener.channel().eventLoop();
                if (futureListener.isSuccess()) {
                    //服务器启动
                    System.out.println("与服务器连接成功：" + finalHost1 + ";" + finalPort1);
                }
                if (!futureListener.isSuccess()) {
                    //服务器未启动 连接tcp服务器不成功
                    System.out.println(finalPort + "第一次连接与服务端断开连接!在10s之后准备尝试重连!");
                    //10秒后重连
                    eventLoop.schedule(() -> doConnect(bootstrap, finalHost, finalPort), 10, TimeUnit.SECONDS);
                }

            });
            channels.put(port, future);
        }
    }

    /**
     * 重新连接tcp服务端
     */
    public static void doConnect(Bootstrap bootstrap , String host, int port) {
        try {
            if (bootstrap != null) {
                //
                bootstrap.remoteAddress(host, port);
                ChannelFuture f = bootstrap.connect().addListener((ChannelFuture futureListener) -> {
                    final EventLoop eventLoop = futureListener.channel().eventLoop();
                    if (!futureListener.isSuccess()) {
                        //连接tcp服务器不成功 10后重连
                        System.out.println(port + "服务器断线-----与服务端断开连接!在10s之后准备尝试重连!");
                        eventLoop.schedule(() -> doConnect(bootstrap, host, port), 10, TimeUnit.SECONDS);
                    }
                });
                channels.put(port, f);
            }
        } catch (Exception e) {
            System.out.println("客户端连接失败!" + e.getMessage());
        }

    }
}
